package codegen

import (
	. "github.com/gonearewe/lua-compiler/compiler/ast"
	. "github.com/gonearewe/lua-compiler/compiler/lexer"
)

// Code generating from block.
func cgBlock(fi *funcInfo,node *Block){
	for _,stat:=range node.Stats{
		cgStat(fi,stat)
	}

	if node.RetExps!=nil{ // has return statement
		cgRetStat(fi,node.RetExps)
	}
}

func cgRetStat(fi *funcInfo,exps []Exp){
	nExps:=len(exps)
	if nExps==0{
		fi.emitReturn(0, 0)
		return
	}

	if nExps == 1 {
		if nameExp, ok := exps[0].(*NameExp); ok {
			if r := fi.slotOfLocVar(nameExp.Name); r >= 0 {
				fi.emitReturn(r, 1)
				return
			}
		}
		if fcExp, ok := exps[0].(*FuncCallExp); ok {
			r := fi.allocReg()
			cgTailCallExp(fi, fcExp, r)
			fi.freeReg()
			fi.emitReturn(r, -1)
			return
		}
	}

	multRet:=isVarargOrFuncCall(exps[nExps-1])
	for i,exp:=range exps{
		r:=fi.allocRegs()
		if i==nExps-1&&multRet{
			cgExp(fi,exp,r,-1)
		}else{
			cgExp(fi,exp,r,1)
		}
	}
	fi.freeRegs(nExps)

	a:=fi.usedRegs
	if multRet{
		fi.emitReturn(a, -1)
	}else{
		fi.emitReturn(a, nExps)
	}
}

func isVarargOrFuncCall(exp Exp)bool{
	switch exp.(type){
	case *VarargExp,*FuncCallExp:
		return true
	}

	return false
}